
 
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <sched.h>
#include "mythread.h"

/*numThreads is the number of threads in the system, determined from command line input at program initialization*/
int numThreads;

/*Number of current thread being created*/
int tNum = 0;

/*Thread body that will print the ids of the threads in the order of a palindrome */
void *printNum(void *threadId) {
	/*Id of the current thread, passed as argument during thread creation*/
	int *threadNum = (int *) threadId;
	int thisThread = *threadNum;
	tNum++;
	/*Prints the thread ID for the first time*/
	printf("%d ", thisThread);
	
	/*Create a new thread and then join it, creates a line of threads waiting on each other, until next to last thread*/
	mythread_t nextThread;
	int errorStatus;
	
	/*Create the next thread*/
	if(thisThread < (numThreads - 1)){
		errorStatus = mythread_create(&nextThread, NULL, printNum, (void *) &tNum);
		if (errorStatus)
		{
			printf("ERROR; return code from mythread_create() for thread %d is %d\n", tNum, errorStatus);
			exit(-1);
		}
	}
	
	/*Join the next thread just created, allows the thread to wait to print its ID again until after the thread numerically after it has printed*/
	void *stat;
	if(thisThread < (numThreads - 1)){
		errorStatus = mythread_join(nextThread, &stat);
		if (errorStatus)
		{
			printf("ERROR; return code from mythread_join() for thread %d is %d\n", tNum, errorStatus);
			exit(-1);
		}
	}
	
	/*Second print of thread ID*/
	printf("%d ", thisThread);
	mythread_exit(NULL);
	return 0;
}

int main(int argc, char *argv[]){
	char* nextCommand;
	nextCommand = argv[1];
	numThreads = 0;
    int j;
	/*Gets the number of threads passed in as a command line parameter at program start*/
    for(j = 0;isdigit(nextCommand[j]);j++)
    {
        numThreads = numThreads * 10 + (nextCommand[j] - '0');
    }
	
	/*printf("Number of threads: %d\n", numThreads);*/
	
	mythread_t thread;
    int errorCheck;
    void *status;
	
	/*Creates the first thread, thread 0, which will in turn start and join thread 1, which will start and join thread 2, etc. until numThreads - 1*/
	errorCheck = mythread_create(&thread, NULL, printNum, (void *) &tNum);
	if (errorCheck)
	{
		printf("ERROR; return code from mythread_create() for thread %d is %d\n", tNum, errorCheck);
		exit(-1);
    }
	
	/*Join thread 0, so that main cannot return until all threads have printed twice*/
	errorCheck = mythread_join(thread, &status);
	if (errorCheck)
	{
		printf("ERROR; return code from mythread_join() for thread %d is %d\n", 0, errorCheck);
		exit(-1);
	}

	/*printf("Main: program completed. Exiting.\n");*/
	printf("\n");
	mythread_exit(NULL);
	
	return 0;
}
